package com.rankeiot.core.util;


/**
 * 创建一个短期Token,当服务器重启后，用户根据token自动登录
 *
 * @author desire
 */
public class TokenUtil {
    /**
     * token中时间所占长度
     */
    private static final int TIME_LENGTH = 7;
    /**
     * 签名长度,md5Base64=24,md5Base62=22/23
     */
    private static final int SIGN_LENGTH = 24;
    /**
     * 数据起始位置
     */
    private static final int DATA_OFFSET = TIME_LENGTH + SIGN_LENGTH;
    /**
     * 最小长度
     */
    private static final int MIN_LENGTH = TIME_LENGTH + SIGN_LENGTH + 1;

    private static final int RADIX = Character.MAX_RADIX;


    private static String global_salt="";
    public static void setGlobalSalt(String salt){
        global_salt=salt;
    }
    public static String getGlobalSalt(){
        return global_salt;
    }
    /**
     * 创建一个带时间戳的token
     *
     * @param value
     * @param expire 过期时间(s) 最大不能超过1/3个周期，约8个月
     * @return
     */
    public static String token(String value, String salt, int expire) {

        long time = (System.currentTimeMillis() / 1000) + expire;
        String t = StringUtil.leftPad(Long.toString(time, RADIX), '0', TIME_LENGTH);
        String v = value + time + salt+global_salt;
        return t + sign(v) + StringUtil.base64(value);
    }

    /**
     * 获取数据
     *
     * @param token
     * @return
     */
    public static String getData(String token) {
        if (token == null) {
            return null;
        }
        //5+24+n
        if (token.length() < MIN_LENGTH) {
            return null;
        }
        return StringUtil.base64Decode(token.substring(DATA_OFFSET));
    }

    /**
     * 获取到期时间
     * @param token
     * @return
     */
    public static long getTime(String token){
       return Long.parseLong(token.substring(0, TIME_LENGTH), RADIX);
    }
    /**
     * 验证token
     *
     * @param token token
     * @return token实际值
     */
    public static boolean validate(String token, String v, String salt) {
        if (token == null) {
            return false;
        }
        //5+24+n
        if (token.length() < MIN_LENGTH) {
            return false;
        }
        long t = Long.parseLong(token.substring(0, TIME_LENGTH), RADIX);
        long now = (System.currentTimeMillis() / 1000) ;
        if(now>t){
            return false;
        }
        return sign(v + t + salt + global_salt).equals(token.substring(TIME_LENGTH, DATA_OFFSET));
    }

    /**
     * 签名
     *
     * @param source 需要签名的值
     * @return 签名后的值
     */
    private static String sign(String source) {
        return StringUtil.md5Base64(source);
    }
}
